package com.todod.base.framework.common.util.office;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.mock.web.MockMultipartFile;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;

public class FileCustomUtils {
    /**
     * 判断目录是否存在，不存在则创建
     * @param fileDir
     */
    public static void fileDirExists(String fileDir){
        File file = new File(fileDir);
        if(!file.exists()){
            file.mkdirs();
            System.out.println("文件创建目录:"+fileDir);
        }
    }
        public static byte[] getFileBytes(String filePath) {
            byte[] buffer = null;
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(filePath);
                int fileSize = fis.available();
                buffer = new byte[fileSize];
                int totalBytesRead = 0;
                while (totalBytesRead < fileSize) {
                    int bytesRemaining = fileSize - totalBytesRead;
                    int bytesRead = fis.read(buffer, totalBytesRead, bytesRemaining);
                    if (bytesRead == -1) {
                        break;
                    }
                    totalBytesRead += bytesRead;
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return buffer;
        }

     // 将文件转换为MultipartFile
    public static MultipartFile file2MultipartFile(File file,String fileType){
        MultipartFile multipartFile = null;
        try(FileInputStream fileInputStream = new FileInputStream(file)) {
            multipartFile = new MockMultipartFile(file.getName(), file.getName(),
                    fileType, fileInputStream);
        } catch (Exception e) {
            System.out.println("文件读取异常"+e);
        }

        return multipartFile;
    }

    // 将MultipartFile转换为文件
    public static void MultiToFile(MultipartFile file, String path,String fileName) {
        //确保上传目录存在
        fileDirExists(path);

        //准备要保存的文件
        File targetFile = new File(path+fileName);
        try {
            //将上传的文件输出到指定的目标文件中
            // 将MultipartFile转换为File
            Files.copy(file.getInputStream(), targetFile.toPath());
//            file.transferTo(targetFile);
        } catch (IOException e) {
            System.out.println("【文件上传至本地】失败，绝对路径：{}"+e);
        }
    }


        // 传入base64编码字符以及保存路径
        public static String Base64ToFile(String base64, String filePath){
            // base64编码字符必须不能包含base64的前缀，否则会报错
            // filePath需要为具体到文件的名称和格式，如111.txt
            // 文件路径需要双斜杠转义，如:  D:\\files\\111.txt

            // 判断是否base64是否包含data:image/png;base64等前缀，如果有则去除
            if (base64.contains("data:image/png;base64")) {
                base64 = base64.substring(22);
//                System.out.println("包含png"+base64);
            }else if (base64.contains("data:image/jpeg;base64")) {
                base64 = base64.substring(23);
//                System.out.println("包含jpeg"+base64);
            }else if (base64.contains("data:application/pdf;base64")) {
                base64 = base64.substring(28);
//                System.out.println("包含pdf"+base64);
            } else {
                base64 = base64.substring(22);
//                System.out.println("包含png"+base64);
            }
            Base64.Decoder decoder = Base64.getDecoder();
            byte[] bytes = decoder.decode(base64);
            for (int i = 0; i<bytes.length; ++i) {
                // 调整异常数据
                if (bytes[i] < 0) {
                    bytes[i] +=256;
                }
            }
            OutputStream outputStream = null;
            InputStream inputStream = new ByteArrayInputStream(bytes);
            // 此处判断文件夹是否存在，不存在则创建除文件外的父级文件夹
            File file = new File(filePath);
            if (!file.exists()) {
                System.out.println("上级目录"+file.getParentFile());
                file.getParentFile().mkdirs();
            }
            try {
                // 生成指定格式文件
                outputStream = new FileOutputStream(filePath);
                byte[] buff = new byte[1024];
                int len = 0;
                while ((len = inputStream.read(buff)) != -1) {
                    outputStream.write(buff, 0, len);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    outputStream.flush();
                    outputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return "生成文件成功!";
        }



//    public static MultipartFile fileToMultipartFile(File file) {
//        FileItem fileItem = creatFileItem(file);
//        MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
//        return multipartFile;
//    }

    public static FileItem creatFileItem(File file) {

        DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory(16, null);
        FileItem fileItem = diskFileItemFactory.createItem("textField", "application/zip", true, file.getName());

        int bytesRead = 0;
        byte[] buffer = new byte[8192];

        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            OutputStream outputStream = fileItem.getOutputStream();
            while ((bytesRead = fileInputStream.read(buffer, 0, 8192)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            Files.copy(file.toPath(), outputStream);
            outputStream.close();
            fileInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return fileItem;
    }
}
